package edu.imac.angryfood.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/** explore the classes

 * 
 */
public class ClassExplorater {

	public static final String STATE_PATH = "edu.imac.angryfood.states.";

	public ClassExplorater() {
	}
	/**
	 * get the id of the state
	 * @param str 
	 * 
	 * @return return the id, or -1 if an error occured
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public int getStateID(String str) throws IllegalArgumentException, IllegalAccessException {
		String className = STATE_PATH + str;
		try {
			Class<?> c = Class.forName(className);
			Field[] f = c.getFields();
			for (int i = 0; i < f.length; ++i) {
				if (f[i].getName() == "ID") {
					return (Integer) f[i].get(c);
				}
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return -1;
	}

	public void exploreField(Object o) {
		@SuppressWarnings("rawtypes")
		Field[] f = ((Class) o).getFields();
		consultField(f, o);
	}

	@SuppressWarnings("rawtypes")
	public void exploreMethode(Object o) {
		Method[] m = null;
		m = ((Class) o).getMethods();
		consultMethod(m);
	}

	public void consultField(Field[] f, Object o) {

		for (int i = 0; i < f.length; ++i) {
			System.out.print(Modifier.toString(f[i].getModifiers()));
			System.out.print(" ");
			System.out.print(f[i].getType().getName());
			System.out.print(" ");
			System.out.print(f[i].getName());
			System.out.print(" = ");
			try {
				System.out.println(f[i].get(o));
			} catch (IllegalAccessException e) {
				System.out.println("Valeur non consultable");
			}
		}
	}

	private void consultMethod(Method[] m) {
		@SuppressWarnings("rawtypes")
		Class[] params = null;
		for (int i = 0; i < m.length; ++i) {
			System.out.print(Modifier.toString(m[i].getModifiers()));
			System.out.print(" ");
			System.out.print(m[i].getReturnType().getName());
			System.out.print(" ");
			System.out.print(m[i].getName());
			System.out.print("(");
			params = m[i].getParameterTypes();
			for (int j = 0; j < params.length; ++j) {
				System.out.print(params[j].getName());
			}
			System.out.println(")");
		}
	}

	Object launchMethod(Object o, Object[] args, String nomMethode)
			throws Exception {
		@SuppressWarnings("rawtypes")
		Class[] paramTypes = null;
		if (args != null) {
			paramTypes = new Class[args.length];
			for (int i = 0; i < args.length; ++i) {
				paramTypes[i] = args[i].getClass();
			}
		}
		Method m = o.getClass().getMethod(nomMethode, paramTypes);
		return m.invoke(o, args);
	}

	void printVal(Object o, String nomChamp) throws Exception {
		Field f = o.getClass().getField(nomChamp);
		System.out.println(f.get(o));
	}

	void setVal(Object o, String nomChamp, Object val) throws Exception {
		Field f = o.getClass().getField(nomChamp);
		f.set(o, val);
	}

}
